package com.genghis.ptas.kmeans;

import weka.clusterers.SimpleKMeans;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: Surc
 * Date: 14-4-20
 * Time: 下午11:21
 * To change this template use File | Settings | File Templates.
 */
public class KMeans {
    private Instances newInstances(int size) {
           FastVector attributes = new FastVector();
           Attribute attribute;
           attributes.addElement(new Attribute("data1"));
           attributes.addElement(new Attribute("data2"));
           return new Instances("Weka", attributes, size);
       }

       private Instances makeInstancesSameWeight(double[][] dataSet) {
           int len = dataSet.length;
           Instances instances = newInstances(len);
           Instance instance;

           for (double[] item : dataSet) {
               instance = new Instance(1, item);
               instances.add(instance);
           }
           return instances;
       }

       public Map<String, Object> calculateForSameWeight(double[][] dataSet, int numOfClusters, int maxIterations) {
           Map<String, Object> returnObj = new HashMap<String, Object>();
           try {
               SimpleKMeans skm = new SimpleKMeans();
               skm.setNumClusters(numOfClusters);
               skm.setDontReplaceMissingValues(true);
               skm.setMaxIterations(maxIterations);
               skm.setDisplayStdDevs(false);
               skm.setPreserveInstancesOrder(true);
               skm.buildClusterer(makeInstancesSameWeight(dataSet));
               returnObj.put("CapitalPoints", instanceToDouble2Array(skm.getClusterCentroids()));
               returnObj.put("EachBelong", skm.getAssignments());
           } catch (Exception e) {
               System.out.println("simple k mean getClusters err:" + e.getMessage());
               returnObj.put("Error", "Error");
           }
           return returnObj;
       }

       public double[][] instanceToDouble2Array(Instances instances) {
           int len = instances.numInstances();
           double[][] resultArr = new double[len][];
           for(int i = 0;  i < len; ++i){
                resultArr[i] = instances.instance(i).toDoubleArray();
           }
           return resultArr;
       }
}
